package com.cnbbx.model;


import com.cnbbx.util.DatabaseDataTypesUtils;
import com.cnbbx.util.StringHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author jinge
 * @email admin(a)cnbbx.com
 */
public class Column {
    /**
     * Reference to the containing table
     */
    private final Table _table;

    /**
     * The java.sql.Types type
     */
    private final int _sqlType;

    /**
     * The sql typename. provided by JDBC driver
     */
    private final String _sqlTypeName;

    /**
     * The name of the column
     */
    private final String _sqlName;

    /**
     * True if the column is a primary key
     */
    private boolean _isPk;

    /**
     * True if the column is a foreign key
     */
    private boolean _isFk;

    /**
     * @todo-javadoc Describe the column
     */
    private final int _size;

    /**
     * @todo-javadoc Describe the column
     */
    private final int _decimalDigits;

    /**
     * True if the column is nullable
     */
    private final String _nullable;

    /**
     * True if the column is indexed
     */
    private final boolean _isIndexed;

    /**
     * True if the column is unique
     */
    private final boolean _isUnique;

    /**
     * Null if the DB reports no default value
     */
    private final String _columnComment;

    private final String _defaultValue;

    /**
     * Get static reference to Log4J Logger
     */
    private static Log _log = LogFactory.getLog(Column.class);

//	String description;
//
//	String humanName;
//
//	int order;
//
//	boolean isHtmlHidden;
//
//	String validateString;

    /**
     * Describe what the DbColumn constructor does
     *
     * @param table         Describe what the parameter does
     * @param sqlType       Describe what the parameter does
     * @param sqlTypeName   Describe what the parameter does
     * @param sqlName       Describe what the parameter does
     * @param size          Describe what the parameter does
     * @param decimalDigits Describe what the parameter does
     * @param isPk          Describe what the parameter does
     * @param isNullable    Describe what the parameter does
     * @param isIndexed     Describe what the parameter does
     * @param isUnique      Describe what the parameter does
     * @param defaultValue  Describe what the parameter does
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for constructor
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for method parameter
     */
    public Column(Table table, int sqlType, String sqlTypeName,
                  String sqlName, int size, int decimalDigits, boolean isPk,
                  boolean isNullable, boolean isIndexed, boolean isUnique,
                  String defaultValue, String columnComment) {
        _table = table;
        _sqlType = sqlType;
        _sqlName = sqlName;
        _sqlTypeName = sqlTypeName;
        _size = size;
        _decimalDigits = decimalDigits;
        _isPk = isPk;
        _nullable = isNullable ? "true" : "false";
        _isIndexed = isIndexed;
        _isUnique = isUnique;
        _defaultValue = defaultValue;
        _columnComment = columnComment;

        _log.debug(sqlName + " isPk -> " + _isPk);

    }

    /**
     * Gets the SqlType attribute of the Column object
     *
     * @return The SqlType value
     */
    public int getSqlType() {
        return _sqlType;
    }

    /**
     * Gets the Table attribute of the DbColumn object
     *
     * @return The Table value
     */
    public Table getTable() {
        return _table;
    }

    /**
     * Gets the Size attribute of the DbColumn object
     *
     * @return The Size value
     */
    public int getSize() {
        return _size;
    }

    /**
     * Gets the DecimalDigits attribute of the DbColumn object
     *
     * @return The DecimalDigits value
     */
    public int getDecimalDigits() {
        return _decimalDigits;
    }

    /**
     * Gets the SqlTypeName attribute of the Column object
     *
     * @return The SqlTypeName value
     */
    public String getSqlTypeName() {
        return _sqlTypeName;
    }

    /**
     * Gets the SqlName attribute of the Column object
     *
     * @return The SqlName value
     */
    public String getSqlName() {
        return _sqlName;
    }

    /**
     * Gets the Pk attribute of the Column object
     *
     * @return The Pk value
     */
    public boolean isPk() {
        return _isPk;
    }

    /**
     * Gets the Fk attribute of the Column object
     *
     * @return The Fk value
     */
    public boolean isFk() {
        return _isFk;
    }

    /**
     * Gets the Indexed attribute of the DbColumn object
     *
     * @return The Indexed value
     */
    public final boolean isIndexed() {
        return _isIndexed;
    }

    /**
     * Gets the Unique attribute of the DbColumn object
     *
     * @return The Unique value
     */
    public boolean isUnique() {
        return _isUnique;
    }

    /**
     * Gets the DefaultValue attribute of the DbColumn object
     *
     * @return The DefaultValue value
     */
    public final String getDefaultValue() {
        return _defaultValue;
    }

    /**
     * 备注
     *
     * @return
     */
    public String getColumnComment() {
        return _columnComment;
    }

    /**
     * Gets the Nullable attribute of the Column object
     *
     * @return The Nullable value
     */
    public String getNullable() {
        return _nullable;
    }

    /**
     * Describe what the method does
     *
     * @return Describe the return value
     * @todo-javadoc Write javadocs for method
     * @todo-javadoc Write javadocs for return value
     */
    public int hashCode() {
        return (getTable().getSqlName() + "#" + getSqlName()).hashCode();
    }

    /**
     * Describe what the method does
     *
     * @param o Describe what the parameter does
     * @return Describe the return value
     * @todo-javadoc Write javadocs for method
     * @todo-javadoc Write javadocs for method parameter
     * @todo-javadoc Write javadocs for return value
     */
    public boolean equals(Object o) {
        // we can compare by identity, since there won't be dupes
        return this == o;
    }

    /**
     * Describe what the method does
     *
     * @return Describe the return value
     * @todo-javadoc Write javadocs for method
     * @todo-javadoc Write javadocs for return value
     */
    public String toString() {
        return getSqlName();
    }

    /**
     * Describe what the method does
     *
     * @return Describe the return value
     * @todo-javadoc Write javadocs for method
     * @todo-javadoc Write javadocs for return value
     */
    protected final String prefsPrefix() {
        return "tables/" + getTable().getSqlName() + "/columns/" + getSqlName();
    }

    /**
     * Sets the Pk attribute of the DbColumn object
     *
     * @param flag The new Pk value
     */
    void setFk(boolean flag) {
        _isFk = flag;
    }

    public String getColumnName() {
        return StringHelper.makeAllWordFirstLetterUpperCase(getSqlName());
    }

    public String getColumnNameLower() {
        return StringHelper.uncapitalize(getColumnName());
    }

    public boolean getIsNotIdOrVersionField() {
        return !isPk();
    }

    public String getValidateString() {
        String result = getNoRequiredValidateString();
        if (getNullable() == "true") {
            result = "required " + result;
        }
        return result;
    }

    public String getNoRequiredValidateString() {
        String result = "";
        if (getSqlName().indexOf("mail") >= 0) {
            result += "validate-email ";
        }
        if (DatabaseDataTypesUtils.isFloatNumber(getSqlType(), getSize(), getDecimalDigits())) {
            result += "validate-number ";
        }
        if (DatabaseDataTypesUtils.isIntegerNumber(getSqlType(), getSize(), getDecimalDigits())) {
            result += "validate-integer ";
        }
//		if(DatabaseDataTypesUtils.isDate(getSqlType(), getSize(), getDecimalDigits())) {
//			result += "validate-date ";
//		}
        return result;
    }

    public boolean getIsDateTimeColumn() {
        return DatabaseDataTypesUtils.isDate(getSqlType(), getSize(), getDecimalDigits());
    }

    public boolean isHtmlHidden() {
        return isPk() && _table.isSingleId();
    }

    public String getJavaType() {
        return DatabaseDataTypesUtils.getPreferredJavaType(getSqlType(), getSize(), getDecimalDigits());
    }
}
